home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / wi_libc.exe / WI.DOC < prev    next >
Encoding:
Text File  |  1991-05-26  |  25.3 KB  |  688 lines

  1. -------------------------[ WI.LIB ]----------for OS/2--------------------------
  2.                       WI.LIB - Wilkes Index Library
  3.                     Copyright (c) 1989 by Roger Wilkes
  4.            Member: Association of Shareware Professionals (ASP)
  5.                   Cost of this Software $40; Gov./Ed. $30
  6.                         Wilkes Software, inc.
  7.                         Memphis, TN 38134
  8.                     or Register on BBS at (901)377-5608
  9. -------------------------------------------------------------------------------
  10.  
  11.     There are a total of six (6) function calls available with this library.
  12. 1) IX_add        - to add keys to an index file
  13. 2) IX_del        - to delete keys from an index file
  14. 3) IX_find_first - to find the first key which meets comparison criteria
  15. 4) IX_find_last  - to find the last key which meets comparison criteria
  16. 5) IX_find_next  - to find the next key
  17. 6) IX_find_prev  - to find the previous key
  18.  
  19. -------------------------------------------------------------------------------
  20.  
  21.     You must insure that "WI.LIB" is available to the linker at link time.
  22. This library is meant to be linked with Microsoft large (-AL) or huge (-AH)
  23. memory models.
  24.  
  25.     Place WI.LIB in your LIB directory and place INDEX.H in your INCLUDE
  26. directory.
  27.  
  28.     The maximum char array key length is 127.  All data types other than this
  29. one can use the "data_type" defines (see INDEX.H).  The character array
  30. data type is formed by anding the length and 0x80.
  31.  
  32. -------------------------------------------------------------------------------
  33.  
  34. 1) Adding a new key to the index file:
  35.    Indexing/Reindexing a file:
  36.  
  37.     int IX_add (long            file_pos,
  38.                 char            *key_addr,
  39.                 unsigned char   data_type,
  40.                 int             file_handle);
  41.  
  42.     file_pos      - is the piece of data which will accompany the key.  This
  43.                     information will be returned to you when you use the
  44.                     IX_find_xxxxx function calls.  If you are working with
  45.                     fixed length records this can be a record length.  If you
  46.                     use this field to contain a record number, you will have
  47.                     to do multiplications to get it to a byte position within
  48.                     the file you are indexing.  You may simply use this field
  49.                     to contain the byte position of the record being indexed.
  50.     key_addr      - contains the address of either
  51.                     1) the key data
  52.                     2) a KEY_STRUCT (see INDEX.H) structure containing up to
  53.                        10 key parts.  The order of importance of the key
  54.                        fields is from lowest index to highest (i.e.
  55.                        KEY_COMPONENT.key[0] to KEY_COMPONENT.key[9]).
  56.     data_type     - specifies that the "key_value" above is either key data
  57.                     or a KEY_STRUCT structure (see INDEX.H).  If data_type
  58.                     designates key data, the length (in bytes) is also known.
  59.  
  60.     RETURNS:    One of the function returns shown in INDEX.H
  61.                     OK          where no errors were detected
  62.                     IX_IO_ERR
  63.                     IX_ERR
  64.                     INV_PARAM
  65.                     INV_NUM_KEYS
  66.  
  67.     EXAMPLE:    if we have a file with the following record layout which we
  68.                 wish to index on the last_name
  69.  
  70. -------------------------------------------------------------------------------
  71.     /* using the Microsoft "C" Optimizing compiler */
  72. #include <index.h>      /* after placing in include dir */
  73. #include <fcntl.h>
  74. #include <sys\types.h>
  75. #include <sys\stat.h>
  76. #include <io.h>
  77. #include <stdlib.h>
  78. #include <stdio.h>
  79.  
  80. #define TRUE        1
  81. #define FALSE       0
  82.  
  83. int nad_file;
  84. int index_file;
  85.  
  86. int num_bytes;
  87. int err;
  88. long file_pos = 0L;
  89.  
  90. struct {
  91.     char        first_name [15];
  92.     char        last_name [15];
  93.     char        addr [30];
  94.     char        city [20];
  95.     char        state [2];
  96.     char        zip [9];
  97. } name_and_addr;
  98.  
  99. #include <os2.h>
  100.  
  101. #define _NOEXIST_FAIL       0x00
  102. #define _NOEXIST_CREATE     0x10
  103. #define _EXIST_FAIL         0x00
  104. #define _EXIST_OPEN         0x01
  105. #define _EXIST_CREATE       0x02
  106.  
  107. #define Close(f)           (errno = DosClose (f))
  108. #define Lseek(f,p,o,l)     (errno = DosChgFilePtr (f, p, o, &l))
  109. #define Read(f,b,l,s)      (errno = DosRead (f, b, l, &s))
  110. #define Write(f,b,l,s)     (errno = DosWrite (f, b, l, &s))
  111.  
  112. int act_cod;
  113.  
  114. main ()
  115. {
  116.     if (DosOpen ("nameaddr.fil", &nad_file, &act_cod, 0L, 0,
  117.                  _NOEXIST_CREATE | _EXIST_OPEN, 0x112, 0L))
  118.     {
  119.        /* do something about the error */
  120.     }
  121.     if (DosOpen ("nameaddr.inx", &index_file, &act_cod, 0L, 0,
  122.                  _NOEXIST_CREATE | _EXIST_OPEN, 0x112, 0L))
  123.     {
  124.       /* do something about the error */
  125.     }
  126.     while (TRUE)
  127.     {
  128.         Read (nad_file, (char *)&name_and_addr,
  129.               sizeof(name_and_addr), num_bytes);
  130.         if (num_bytes == 0)     /* end of file */
  131.             break;
  132.         if (num_bytes != sizeof(name_and_addr))
  133.         {
  134.            /* take care of short read */
  135.         }
  136.         err = IX_add (file_pos, name_and_addr.last_name,
  137.                       sizeof(name_and_addr.last_name)+0x80, index_file);
  138.                    /* 0x80 is simply the high order bit
  139.                       of the data_type.  For all other data
  140.                       types you can use the #define names
  141.                       (see INDEX.H) */
  142.         switch (err)
  143.         {
  144.             case OK:
  145.                 printf ("NAME: %15.15s indexed\n",
  146.                         name_and_addr.last_name);
  147.                 break;
  148.             case IX_IO_ERR:
  149.                 printf ("IO Error on \"nameaddr.inx\" file\n");
  150.                 break;
  151.             case IX_ERR:
  152.                 printf ("Index File is corrupted\n");
  153.                 break;
  154.             case INV_PARAM:
  155.                 printf ("Function Call Parameters don't match\n");
  156.                 printf (" information already in \"nameaddr.inx\"\n");
  157.                 break;
  158.             case INV_NUM_KEYS:
  159.                 printf ("The number of key fields does not match\n");
  160.                 printf (" information already in \"nameaddr.inx\"\n");
  161.                 break;
  162.             default: break;
  163.         }
  164.         if (err)
  165.             break;
  166.         file_pos += sizeof(name_and_addr);
  167.     }
  168. }
  169. -------------------------------------------------------------------------------
  170.  
  171. 2) Deleting an index entry from an index file:
  172.  
  173.     int IX_del (char            *key_addr,
  174.                 long            file_pos,
  175.                 unsigned char   data_type,
  176.                 int             file_handle);
  177.  
  178.     key_addr      - contains the address of either
  179.                     1) the key data
  180.                     2) a KEY_STRUCT (see INDEX.H) structure containing up to
  181.                        10 key parts.  The order of importance of the key
  182.                        fields is from lowest index to highest (i.e.
  183.                        KEY_COMPONENT.key[0] to KEY_COMPONENT.key[9]).
  184.     file_pos      - is the piece of data which will accompany the key.  This
  185.                     information will be returned to you when you use the
  186.                     IX_find_xxxxx function calls.  If you are working with
  187.                     fixed length records this can be a record length.  If you
  188.                     use this field to contain a record number, you will have
  189.                     to do multiplications to get it to a byte position within
  190.                     the file you are indexing.  You may simply use this field
  191.                     to contain the byte position of the record being indexed.
  192.                     The file position field is required in the delete to
  193.                     differentiate between duplicate keys and must be the same
  194.                     as used during IX_add.
  195.     data_type     - specifies that the "key_value" above is either key data
  196.                     or a KEY_STRUCT structure (see INDEX.H).  If data_type
  197.                     designates key data, the length (in bytes) is also known.
  198.  
  199.     RETURNS:    One of the function returns shown in INDEX.H
  200.                     OK          where no errors were detected
  201.                     IX_IO_ERR
  202.                     IX_ERR
  203.                     INV_PARAM
  204.                     INV_NUM_KEYS
  205.  
  206.     EXAMPLE:    if we have a file with the following record layout which we
  207.                 wish to delete all indexes from.  NOTE: we could accomplish
  208.                 the same thing, in this case, by deleting the file; except
  209.                 here, the file size will not change (i.e. not be clean).
  210.  
  211. -------------------------------------------------------------------------------
  212.     /* using the Microsoft "C" Optimizing compiler */
  213. #include <index.h>      /* after placing in include dir */
  214. #include <fcntl.h>
  215. #include <sys\types.h>
  216. #include <sys\stat.h>
  217. #include <io.h>
  218. #include <stdlib.h>
  219. #include <stdio.h>
  220.  
  221. int nad_file;
  222. int index_file;
  223.  
  224. int num_bytes;
  225. int err;
  226. long file_pos = 0L;
  227.  
  228. struct {
  229.     char        first_name [15];
  230.     char        last_name [15];
  231.     char        addr [30];
  232.     char        city [20];
  233.     char        state [2];
  234.     char        zip [9];
  235. } name_and_addr;
  236.  
  237. #include <os2.h>
  238.  
  239. #define _NOEXIST_FAIL       0x00
  240. #define _NOEXIST_CREATE     0x10
  241. #define _EXIST_FAIL         0x00
  242. #define _EXIST_OPEN         0x01
  243. #define _EXIST_CREATE       0x02
  244.  
  245. #define Close(f)           (errno = DosClose (f))
  246. #define Lseek(f,p,o,l)     (errno = DosChgFilePtr (f, p, o, &l))
  247. #define Read(f,b,l,s)      (errno = DosRead (f, b, l, &s))
  248. #define Write(f,b,l,s)     (errno = DosWrite (f, b, l, &s))
  249.  
  250. int act_cod;
  251.  
  252. main ()
  253. {
  254.     if (DosOpen ("nameaddr.fil", &nad_file, &act_cod, 0L, 0,
  255.                  _NOEXIST_CREATE | _EXIST_OPEN, 0x112, 0L))
  256.     {
  257.        /* do something about the error */
  258.     }
  259.     if (DosOpen ("nameaddr.inx", &index_file, &act_cod, 0L, 0,
  260.                  _NOEXIST_CREATE | _EXIST_OPEN, 0x112, 0L))
  261.     {
  262.       /* do something about the error */
  263.     }
  264.     while (TRUE)
  265.     {
  266.         Read (nad_file, (char *)&name_and_addr,
  267.               sizeof(name_and_addr), num_bytes);
  268.         if (num_bytes == 0)     /* end of file */
  269.             break;
  270.         if (num_bytes != sizeof(name_and_addr))
  271.         {
  272.             /* take care of short read */
  273.         }
  274.         err = IX_del (name_and_addr.last_name, file_pos,
  275.                       sizeof(name_and_addr.last_name)+0x80, index_file);
  276.                    /* 0x80 is simply the high order bit
  277.                       of the data_type.  For all other data
  278.                       types you can use the #define names
  279.                       (see INDEX.H) */
  280.         switch (err)
  281.         {
  282.         case OK:
  283.             printf ("NAME: %15.15s index Deleted\n",
  284.                     name_and_addr.last_name);
  285.             break;
  286.         case IX_IO_ERR:
  287.             printf ("IO Error on \"nameaddr.inx\" file\n");
  288.             break;
  289.         case IX_ERR:
  290.             printf ("Index File is corrupted\n");
  291.             break;
  292.         case INV_PARAM:
  293.             printf ("Function Call Parameters don't match\n");
  294.             printf (" information already in \"nameaddr.inx\"\n");
  295.             break;
  296.         case INV_NUM_KEYS:
  297.             printf ("The number of key fields does not match\n");
  298.             printf (" information already in \"nameaddr.inx\"\n");
  299.             break;
  300.         default: break;
  301.         }
  302.         if (err)
  303.             break;
  304.         file_pos += sizeof(name_and_addr);
  305.     }
  306. }
  307. -------------------------------------------------------------------------------
  308.  
  309. 3) Finding indexed keys in an index file:
  310.  
  311.     int IX_find_first (FIND_IX          *fix,
  312.                        char             *key_addr,
  313.                        int              find_condition,
  314.                        int              file_handle,
  315.                        unsigned char    data_type);
  316.  
  317.     int IX_find_last  (FIND_IX          *fix,
  318.                        char             *key_addr,
  319.                        int              find_condition,
  320.                        int              file_handle,
  321.                        unsigned char    data_type);
  322.  
  323.     int IX_next       (FIND_IX          *fix);
  324.  
  325.     int IX_prev       (FIND_IX          *fix);
  326.  
  327.     fix           - is the address of the FIND_IX structure
  328.                     typedef struct
  329.                     {
  330.                         long            data_rec;   /* returned file pos */
  331.                         long            recno[3];   /* used internally */
  332.                         int             ix[3];      /* used internally */
  333.                         unsigned char   data_type;  /* used internally */
  334.                         unsigned char   find_type;  /* used internally */
  335.                         VALUE           *val        /* used internally */
  336.                         int             fn;         /* used internally */
  337.                     } FIND_IX;
  338.                     the data_rec field contains the file position of the
  339.                     indexed file, in order to locate the proper record.
  340.     key_addr      - contains the address of either
  341.                     1) the key data
  342.                     2) a KEY_STRUCT (see INDEX.H) structure containing up to
  343.                        10 key parts.  The order of importance of the key
  344.                        fields is from lowest index to highest (i.e.
  345.                        KEY_COMPONENT.key[0] to KEY_COMPONENT.key[9]).
  346.                     You must insure that the value this address points to
  347.                     does not change between IX_find_first/IX_find_last
  348.                     calls and IX_find_next/IX_find_prev calls.
  349.     find_condition- is one of the file conditions listed in INDEX.H
  350.                     1) FIND_EQL
  351.                     2) FIND_GTR
  352.                     3) FIND_LSS
  353.                     4) FIND_NEQ
  354.                     5) FIND_GEQ
  355.                     6) FIND_LEQ
  356.     file_handle   - is the file number of the open file in which the indexes
  357.                     will be found.
  358.     data_type     - specifies that the "key_value" above is either key data
  359.                     or a KEY_STRUCT structure (see INDEX.H).  If data_type
  360.                     designates key data, the length (in bytes) is also known.
  361.  
  362.     EXAMPLE:    if we have a file with the following record layout which we
  363.                 wish find and print all records where the last name is
  364.                 greater than or equal to "Marty" - remember that upper and
  365.                 lower case are different:
  366.  
  367. -------------------------------------------------------------------------------
  368.     /* using the Microsoft "C" Optimizing compiler */
  369. #include <index.h>      /* after placing in include dir */
  370. #include <fcntl.h>
  371. #include <sys\types.h>
  372. #include <sys\stat.h>
  373. #include <io.h>
  374. #include <stdlib.h>
  375. #include <stdio.h>
  376.  
  377. int nad_file;
  378. int index_file;
  379.  
  380. int num_bytes;
  381. int err;
  382. long file_pos = 0L;
  383. FIND_IX fix;
  384. char *compare_field = "Marty          ";
  385.  
  386. struct {
  387.     char        first_name [15];
  388.     char        last_name [15];
  389.     char        addr [30];
  390.     char        city [20];
  391.     char        state [2];
  392.     char        zip [9];
  393. } name_and_addr;
  394.  
  395. #include <os2.h>
  396.  
  397. #define _NOEXIST_FAIL       0x00
  398. #define _NOEXIST_CREATE     0x10
  399. #define _EXIST_FAIL         0x00
  400. #define _EXIST_OPEN         0x01
  401. #define _EXIST_CREATE       0x02
  402.  
  403. #define Close(f)           (errno = DosClose (f))
  404. #define Lseek(f,p,o,l)     (errno = DosChgFilePtr (f, p, o, &l))
  405. #define Read(f,b,l,s)      (errno = DosRead (f, b, l, &s))
  406. #define Write(f,b,l,s)     (errno = DosWrite (f, b, l, &s))
  407.  
  408. int act_cod;
  409.  
  410. main ()
  411. {
  412.     if (DosOpen ("nameaddr.fil", &nad_file, &act_cod, 0L, 0,
  413.                  _NOEXIST_FAIL | _EXIST_OPEN, 0x112, 0L))
  414.     {
  415.        /* do something about the error */
  416.     }
  417.     if (DosOpen ("nameaddr.inx", &index_file, &act_cod, 0L, 0,
  418.                  _NOEXIST_FAIL | _EXIST_OPEN, 0x112, 0L))
  419.     {
  420.        /* do something about the error */
  421.     }
  422.  
  423.     err = IX_find_first (&fix, compare_field,
  424.                          FIND_GEQ, index_file,
  425.                          sizeof(name_and_addr.last_name)+0x80);
  426.     while (TRUE)
  427.     {
  428.         switch (err)
  429.         {
  430.         case OK:
  431.             lseek (nad_file, fix.data_rec, SEEK_SET);
  432.             Read (nad_file, (char *)&name_and_addr,
  433.                   sizeof(name_and_addr), num_bytes);
  434.             if (num_bytes != sizeof(name_and_addr))
  435.             {
  436.                 /* take care of short read */
  437.             }
  438.             printf ("NAME: %15.15s %15.15s | CITY/ST: %20.20s %2.2s\n",
  439.                     name_and_addr. first_name,
  440.                     name_and_addr. last_name,
  441.                     name_and_addr. city,
  442.                     name_and_addr. state);
  443.             break;
  444.         case IX_IO_ERR:
  445.             printf ("IO Error on \"nameaddr.inx\" file\n");
  446.             break;
  447.         case IX_ERR:
  448.             printf ("Index File is corrupted\n");
  449.             break;
  450.         case NOT_FOUND:
  451.             printf ("No Matching Keys Found\n");
  452.             break;
  453.         case NO_MORE:
  454.             printf ("No More Matching Keys Found\n");
  455.             break;
  456.         case INV_PARAM:
  457.             printf ("Function Call Parameters don't match\n");
  458.             printf (" information already in \"nameaddr.inx\"\n");
  459.             break;
  460.         case INV_NUM_KEYS:
  461.             printf ("The number of key fields does not match\n");
  462.             printf (" information already in \"nameaddr.inx\"\n");
  463.             break;
  464.         default: break;
  465.         }
  466.         if (err)
  467.             break;
  468.         err = IX_find_next (&fix);
  469.     }
  470. }
  471. -------------------------------------------------------------------------------
  472.  
  473. 4) Data Types:
  474.  
  475.     #define             "C"
  476.     -------             ---
  477.     ftCHAR              char
  478.     ftUCHAR             unsigned char
  479.     ftSCHAR             signed char
  480.     ftUNS_INT           unsigned int
  481.     ftINT               int
  482.     ftULONG             unsigned long
  483.     ftLONG              long
  484.     ftFLOAT             float
  485.     ftDOUBLE            double
  486.     ftH_BCD_1 - 10      -------         1 to 10 char BCD field with
  487.                                         sign at front of field
  488.     ftT_BCD_1 - 10      -------         1 to 10 char BCD field with
  489.                                         sign at end of field
  490.     ftSTRUCT            -------         multi field key where the
  491.                                         location of the fields is
  492.                                         specified in the KEY_STRUCT
  493.                                         structure (see INDEX.H)
  494. -------------------------------------------------------------------------------
  495.  
  496. 5) KEY_STRUCT structure for multi-field keys:
  497.  
  498.     typedef struct
  499.     {
  500.         unsigned char       num_keys;
  501.         struct
  502.         {
  503.             unsigned char   data_type;      /* data_type for this field */
  504.             VALUE           *val;           /* addr of this key field */
  505.         } key [10];
  506.     } KEY_STRUCT;
  507.  
  508.     If we wish to take the following record layout and index it on
  509. last_name and first_name (in that order):
  510.  
  511.     struct {
  512.         char        first_name [15];
  513.         char        last_name [15];
  514.         char        addr [30];
  515.         char        city [20];
  516.         char        state [2];
  517.         char        zip [9];
  518.     } name_and_addr;
  519.  
  520. with
  521.  
  522.     KEY_STRUCT      keys;
  523.  
  524. the keys would populated as follows:
  525.  
  526.     keys. num_keys = 2;
  527.     keys. key [0]. data_type = sizeof(name_and_addr.last_name) | 0x80;
  528.     keys. key [0]. val = (VALUE *)name_and_addr.last_name;
  529.     keys. key [1]. data_type = sizeof(name_and_addr.first_name) | 0x80;
  530.     keys. key [1]. val = (VALUE *)name_and_addr.first_name;
  531.  
  532. the key_addr parameter for the function calls would be "(char *)&keys"
  533. and the data_type parameter to the function calls would be ftSTRUCT.
  534.  
  535. NOTE: that the maximum number of key fields is 10.  This should be enough
  536.     for any reasonable purpose.  If you require more you can stack the
  537.     keys in some instances (char arrays back to back can be considered
  538.     a single field as long as the cumulative sizes are < 128 characters).
  539. -------------------------------------------------------------------------------
  540.  
  541.  
  542.  
  543.  
  544.  
  545.             LICENSE
  546.             -------
  547.  
  548.     Wilkes INDEX, version 1.0, is being distributed under the "shareware" or
  549. user supported concept.  This software is NOT free software.  The use or
  550. reproduction of this software outside of the limits specified in this license
  551. agreement is prohibited.
  552.  
  553.     Non-registered users are granted a limited license to use this software
  554. for a period not to exceed thirty days.  During this period they should test
  555. and evaluate the software to determine if it will meet their needs. The use of
  556. this software beyond this limited time period requires registration.
  557. Non-registered users are not allowed to distribute this software without the
  558. express written permission of Wilkes Software inc.  The only exceptions to this
  559. distribution restriction are SYSOPS of electronic bulletin boards and
  560. distributors of public domain and user supported software.  SYSOPS and
  561. software distributors must abide by the copying restrictions specified below.
  562.  
  563.     Registered users are granted the right to use Wilkes INDEX on only
  564. one computer at any time.  Site licensing agreements are available for
  565. businesses, corporations, and government agencies.  Registered users are also
  566. granted the right to copy and distribute Wilkes INDEX subject to the
  567. following conditions.
  568.  
  569.     Wilkes INDEX must be copied in its original unmodified form.
  570.  
  571.     All of the files must be included in the copy.
  572.  
  573.     Wilkes INDEX may not be distributed in conjunction with any other
  574.     product without the express written consent of Wilkes Software inc.
  575.  
  576.  
  577.  
  578.  
  579.                 WARRANTY
  580.                 --------
  581.  
  582.     Wilkes Software makes no warranty of any kind, express or implied,
  583. including without limitation, any warranties of merchantability and or fitness
  584. for a particular purpose.  Wilkes Software shall not be liable for any
  585. damages, whether direct, indirect, special or consequential arising from a
  586. failure of this software to operate in the manner desired by the user.
  587. Wilkes Software shall not be liable for any damage to data or property which
  588. may be caused directly or indirectly by use of the program.
  589.  
  590.     IN NO EVENT WILL Wilkes Software BE LIABLE TO YOU FOR ANY DAMAGES,
  591. INCLUDING ANY LOST PROFITS, LOST SAVINGS OR OTHER INCIDENTAL OR CONSEQUENTIAL
  592. DAMAGES ARISING OUT OF YOUR USE OR INABILITY TO USE THE PROGRAM, OR FOR ANY
  593. CLAIM BY ANY OTHER PARTY.
  594.  
  595.  
  596.  
  597.  
  598.  
  599.             REGISTRATION FEES
  600.             -----------------
  601.  
  602. The registration fee for Wilkes INDEX, version 1.0, is only $40.00, with
  603. quantity discount for 10 or more copies to $25.00/copy.
  604.  
  605. Government and Education registration fee is only $30.00, with quantity
  606. discount for 10 or more copies to $20.00/copy.
  607.  
  608. You may fill out and return the registration page below or register on-line
  609. at (901)377-5608.
  610.  
  611. Future updates of the site license copy are provided as follows. The first
  612. update is free.   All others $15.00.
  613.  
  614. Prices are for a titled master copy and cover all charges including shipping.
  615. Licensees will be informed when updates become available and given the option
  616. to update at will.  There is NO penalty for skipping updates.
  617.  
  618.  
  619.  
  620.  
  621.  
  622.     If you should require assistance in the use of the Wilkes INDEX, you
  623. may call the WSI BBS at (901)377-5608.
  624.  
  625.     If you like this software please let me know.  If you have enhancements
  626. you would like to see in this software, please let me know those also.  If you
  627. have complaints about the way the Wilkes INDEX functions I would even like to
  628. hear those.
  629.  
  630.     The following is a registration form.  In addition to the licensing use,
  631. I will also use this information to correlate requests for additional
  632. functionality and for Wilkes Software mailing list purpose (only by Wilkes
  633. Software).  When Wilkes Software offers other software into the shareware
  634. system in the future, information will be sent to registered users of the
  635. Wilkes INDEX.  If you register a non-current version I will send the
  636. current version to you.
  637.  
  638.  
  639.  
  640. to: Wilkes Software, inc.
  641.     5231 Longwood Drive
  642.     Memphis, TN  38134
  643.  
  644.  
  645.     Name (first) ____________________  (last) ____________________
  646.  
  647.     Title    ___________________________________
  648.  
  649.     Company  ___________________________________
  650.  
  651.     Address  ___________________________________
  652.  
  653.              ___________________________________
  654.  
  655.     City     _________________________  State  ___  Zip code _______
  656.  
  657.     Where software obtained: ________________________________________
  658.  
  659.     Version of Wilkes INDEX for Microsoft C: 1.0
  660.  
  661.     System: ____________________
  662.  
  663.     OS/2 Version: _____
  664.  
  665.     Phone: (____) ____ - _____
  666.  
  667.     If Gov./Ed. please specify: _____________________________________
  668.  
  669. COST:
  670.  
  671.     $40/copy; 10+ copies $25/copy
  672.     Gov./Ed. $30/copy; 10+ copies $20/copy
  673.  
  674.     Tennessee Residents: sales tax is 7.75%
  675.  
  676.     # copies _________ x your price: ____________ + TN sales tax __________
  677.  
  678.         = Total _________________
  679.  
  680. METHOD OF PAYMENT:
  681.  
  682.     VISA/MASTERCARD/CHECK: __________
  683.  
  684.     V/MC account #: ___________________________  Expiration Date: _________
  685.  
  686.     Signature: __________________________________________________
  687.  
  688.